/***************************************************************************
 *  Filename: processmanager.cpp
 *  Class: ProcessManager
 *
 *  Copyright 2012  Xander van Kooten
 *  <xandervk@gmail.com>
 *
 *  Copyright 2012  Mario Henrique Voorsluys
 *  <forcaeluz@gmail.com>
 *
 ****************************************************************************/

/*
 *
 * This file is part of Parsax-Remote-Controller.
 *
 *    Parsax-Remote-Controller is free software: you can redistribute it
 *    and/or modify it under the terms of the GNU General Public License
 *    as published by the Free Software Foundation, either version 3 of the
 *    License, or (at your option) any later version.
 *
 *    Parsax-Remote-Controller is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Parsax-Remote-Controller.
 *    If not, see <http://www.gnu.org/licenses/>.
 */

#include "processmanager.h"
#include <QDebug>
ProcessManager::ProcessManager(QString tid, QObject *parent) :
    QObject(parent)
{
    qDebug() << "[ProcessManager] Object created with id" << tid;
    connect(&myProcess, SIGNAL(readyReadStandardError()), SLOT(sendCle()), Qt::UniqueConnection);
    connect(&myProcess, SIGNAL(readyReadStandardOutput()), SLOT(sendClo()), Qt::UniqueConnection);
    connect(&myProcess, SIGNAL(stateChanged(QProcess::ProcessState)), SLOT(sendStatus()), Qt::UniqueConnection);
    id = tid;
}

ProcessManager::~ProcessManager(){
    qDebug() << "[ProcessManager] Deleting object";
    myProcess.close();
}

void ProcessManager::start(){
    qDebug() << "[ProcessManager] Starting";
    switch(myProcess.state()){
    case QProcess::Running:
    case QProcess::Starting:
        qWarning() << "[ProcessManager] Process already started";
        break;
    case QProcess::NotRunning:
        myProcess.start(program, params);
        if(!myProcess.waitForStarted()){
            qDebug() << "[ProcessManager] Unbale to start program:" << myProcess.errorString();
        }
        break;
    default:
        qWarning() << "[ProcessManager] Unknown process state";
    }
}

void ProcessManager::stop(){
    qDebug() << "[ProcessManager] Stopping";
    switch(myProcess.state()){
    case QProcess::Running:
        myProcess.close();
        myProcess.waitForFinished();
        break;
    case QProcess::Starting:
    case QProcess::NotRunning:
        qWarning() << "[ProcessManager] Trying to stop something that has not been started";
        qWarning() << "[ProcessManager] State" << myProcess.state();
        break;
    default:
        qWarning() << "[ProcessManager] Unknown process state";
    }
}

void ProcessManager::restart(){
    qDebug() << "[ProcessManager] Restart";
    stop();
    start();
}

void ProcessManager::setProgram(QString tprogram){
    program = tprogram;
}

void ProcessManager::setParameters(QStringList tparams){
    params = tparams;
}

void ProcessManager::sendCle(){
    QString msg = myProcess.readAllStandardError();
    emit cloReceived(id, 1, msg);
}

void ProcessManager::sendClo(){
    QString msg = myProcess.readAllStandardOutput();
    emit cloReceived(id, 0, msg);
}

void ProcessManager::sendStatus(){
    switch(myProcess.state()){
    case QProcess::Starting:
        emit statusReceived(id, "starting");
        break;
    case QProcess::Running:
        emit statusReceived(id, "running");
        break;
    case QProcess::NotRunning:
        emit statusReceived(id, "notrunning");
        break;
    }
}

QString ProcessManager::getProgram(){
    return program;
}

QString ProcessManager::getStatus(){
    switch(myProcess.state()){
    case QProcess::Starting:
        return "starting";
        break;
    case QProcess::Running:
        return "running";
        break;
    case QProcess::NotRunning:
        return "notrunning";
        break;
    }
}

void ProcessManager::sendCmdToProcess(QString cmd){
    myProcess.write(QByteArray().append(cmd));
}


